package utilities;

/**
 * Creates a Vector class which represents any vector in x,y plane. It could be 
 * used to represent position or velocity. 
 * 
 * We decided to use Vector instead of Java's built-in PVector class because
 * we want to make it customizable. 
 * 
 * @author Ga-Young Joung and Perry Zheng
 */
import java.util.ArrayList;
import java.util.Random;

public class Vector {
	public double x;
	public double y;
	
	/**
	 * Constructs a default vector class or a zero vector. 
	 */
	public Vector() {
		this.x = 0;
		this.y = 0;
	}
	
	/**
	 * Constructs a vector with specified double x and y coordinates
	 * @param x the x component
	 * @param y the y component
	 */
	public Vector(double x, double y) {
		this.x = x;
		this.y = y;
	}
	
	/**
	 * Constructs a vector with specified int x and y coordinates
	 * @param x the x component
	 * @param y the y component
	 */
	public Vector(int x, int y) {
		this.x = x;
		this.y = y;
	}
	
	/**
	 * Constructs a vector based on a specified vector p
	 * @param p the specified vector p
	 */
	public Vector(Vector p) {
		this.x = p.x;
		this.y = p.y;
	}
	
	/**
	 * Move to a specified location
	 * @param x the resulting x-component
	 * @param y the resulting y-component
	 */
	public void move(double x, double y) {
		this.x = x;
		this.y = y;
	}
	
	/**
	 * Translates this point, at location (x, y), by dx along the 
	 * x axis and dy along the y axis
	 * so that it now represents the point (x + dx, y + dy)
	 * @param dx
	 * @param dy
	 */
	public void translate(double dx, double dy) {
		this.x += dx;
		this.y += dy;
	}
	
	/**
	 * Translates this point, at location (x, y), by dx along the 
	 * x axis and dy along the y axis
	 * so that it now represents the point (x + dx, y + dy).
	 * @param velocityVector
	 */
	public void translate(Vector velocityVector) {
		this.x += velocityVector.x;
		this.y += velocityVector.y;
	}
	
	/**
	 * Give a string representation of this object
	 */
	public String toString() {
		return "(" + this.x + ", " + this.y + ")";
	}
	
	/**
	 * Return the result of current vector adding to another vector
	 * @param another the other vector to be added
	 * @return the result of current vector adding to another vector
	 */
	public Vector add(Vector another) {
		Vector p = new Vector();
		p.x = this.x + another.x;
		p.y = this.y + another.y;
		return p;
	}
	
	/**
	 * Return the result of this vector subtracting another vector 
	 * @param another the result of current vector subtracting another vector
	 * @return the result of current vector subtracting another vector
	 */
	public Vector subtract(Vector another) {
		Vector p = new Vector();
		p.x = this.x - another.x;
		p.y = this.y - another.y;
		return p;
	}
	
	/**
	 * Return the result of this vector multiplying by a scaling constant
	 * @param constant the constant to be multiplied
	 * @return the result of current vector multiplying by a constant
	 */
	public Vector multiply(int constant) {
		Vector p = new Vector();
		p.x = this.x * constant;
		p.y = this.y * constant;
		return p;
	}
	
	/**
	 * Return the result of this vector dividing by a constant
	 * @param constant the scaling constant
	 * @return the result of current vector dividing by a constant
	 */
	public Vector divide(int constant) {
		Vector p = new Vector();
		if (constant != 0) {
			p.x = this.x/constant;
			p.y = this.y/constant;
		}
		return p;
	}
	
	/**
	 * Perturb this vector by a little bit (by increase between 0 and 1)
	 */
	public void perturb() {
		Random r = new Random();
		this.translate(cast(r.nextBoolean())*r.nextDouble(),cast(r.nextBoolean())*r.nextDouble());
	}
	
	/**
	 * Cast the boolean into 1 or -1 depending on it's positive and negative
	 * @param bool 
	 * @return 1 or -1 depending on whether it's positive or negative
	 */
	public int cast(boolean bool) {
		return bool==true?1:-1;
	}
	/**
	 * checks if this vector is a zero vector
	 * @return true if it's a zero vector
	 */
	public boolean isZero() {
		return (int)this.x==0 && (int)this.y==0;
	}
	
	/**
	 * return the vector that's the result of adding a list of vectors
	 * @param list an arraylist of vectors
	 * @return the vector that's the rsult of adding a list of vectors
	 */
	public Vector add(ArrayList<Vector> list) {
		Vector p = new Vector(this);
		for (Vector v : list) {
			p = p.add(v);
		}
		return p;
	}
	
	public static void main(String[] args) {
		Vector a = new Vector(10,.8);
		Vector b = new Vector(5,3);
		ArrayList<Vector> list = new ArrayList<Vector>();
		list.add(a);
		list.add(b);
		Vector ret = new Vector();
	}
	
}
